package com.ibm.cognos.imt.service;

import com.cognos.developer.schemas.bibus._3.*;
import com.ibm.cognos.imt.config.BiServerConfig;
import com.ibm.cognos.imt.fm.CognosModel;
import com.ibm.cognos.imt.model.SavedReport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import javax.xml.rpc.ServiceException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by eric on 7/7/2014.
 */
@Service
@Scope("singleton")
public class CognosCMService {

    @Autowired
    BiServerConfig biServerConfig;

    private ContentManagerService_PortType cmService = null;

    private ContentManagerService_PortType getCmService() throws Exception {
        if (cmService == null) {
            connectToReportServer();
        }
        return cmService;
    }

    public void connectToReportServer() throws Exception {
        ContentManagerService_ServiceLocator cmServiceLocator = new ContentManagerService_ServiceLocator();
        System.out.println("connect to server "+biServerConfig.dispatcherURI());
        cmService = cmServiceLocator.getcontentManagerService(new java.net.URL(biServerConfig.dispatcherURI()));
    }

    public CognosModel getModel() throws Exception {
        PropEnum props[] = new PropEnum[]{PropEnum.searchPath, PropEnum.model};
        BaseClass[] model = getCmService().query(new SearchPathMultipleObject("/content/folder[@name='Samples']/folder[@name='Models']/package[@name='GO Sales (query)']/model[@name='model']"), props, new Sort[]{}, new QueryOptions());
//      BaseClass[] model = getCmService().query(new SearchPathMultipleObject(biServerConfig.getModelPath()), props, new Sort[]{}, new QueryOptions());
        String modelXmlString = ((Model)model[0]).getModel().getValue();

//          String modelFile="c:\\model"+i+".xml";
//			File oFile = new File(modelFile);
//			FileOutputStream fos = new FileOutputStream(oFile);
//			String temp=((Model)model[i]).getModel().getValue();
//			ByteArrayInputStream bais = new ByteArrayInputStream(temp.getBytes("UTF-8"));
//			System.out.println("Writing model data to file "+modelFile);
//			while (bais.available() > 0) {
//					fos.write(bais.read());
//		    };
//			fos.flush();
//			fos.close();

        CognosModel m = new CognosModel(modelXmlString);
        System.out.println(m);
        return m;
    }

    public List<SavedReport> getAllReports() throws Exception, ServiceException {
        List<SavedReport> output = new ArrayList<SavedReport>();
        PropEnum props[] = new PropEnum[]{PropEnum.searchPath, PropEnum.defaultName, PropEnum.metadataModel, PropEnum.metadataModelPackage};
        // set the QueryOptions referenceProps option
        PropEnum referenceProps[] = new PropEnum[]{PropEnum.defaultName, PropEnum.searchPath, PropEnum.version};
        RefProp refPropArray[] = {new RefProp()};
        refPropArray[0].setProperties(referenceProps);
        refPropArray[0].setRefPropName(PropEnum.metadataModelPackage);

        QueryOptions qops = new QueryOptions();
        qops.setRefProps(refPropArray);

        Sort sortOptions[] = {new Sort()};
        sortOptions[0].setOrder(OrderEnum.ascending);
        sortOptions[0].setPropName(PropEnum.defaultName);
        BaseClass bc[] = getCmService().query(new SearchPathMultipleObject("//report"), props, sortOptions, qops);
//            output = output.concat("Reports:\n\n");

        for (int i = 0; i < bc.length; i++) {
            BaseClassArrayProp pkg = ((AuthoredReport) bc[i]).getMetadataModelPackage();
            String packageName = "Package name not available";
            String packageSearchPath = "Package Search Path not available";
            if (pkg.getValue() != null) {
                packageName = ((AuthoredReport) bc[i]).getMetadataModelPackage().getValue()[0].getDefaultName().getValue();
                packageSearchPath = ((AuthoredReport) bc[i]).getMetadataModelPackage().getValue()[0].getSearchPath().getValue();
            }

            // Statement to only get the information of a desired package from the content store.
            // compare "packname" variable declared at start with the packageName found for report.

//                System.out.println(packageName + " -> " + bc[i].getDefaultName().getValue());
            String reportName = bc[i].getDefaultName().getValue();
            String reportSearchPath = bc[i].getSearchPath().getValue();
            output.add(new SavedReport(reportName, reportSearchPath));
        }

//            System.out.println(output.size());
        return output;

    }

}
